home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 351-375 / disk_362 / puzz / source / audio.c next >
C/C++ Source or Header  |  1992-05-06  |  6KB  |  289 lines

  1. /*  audio.c        Martin Round    November '89
  2.  
  3.     This code is taken straight from Steven A. Bennett's 'scales.c'
  4.     Thanks Steven!
  5.     I've mostly left the code in it's original state, only putting in
  6.     a few function prototypes and 'voids' to stop my compiler issuing
  7.     me with warnings.
  8.     I've also stripped comments and altered bracket indenting into my own
  9.     weird style - sorry Steven!  Actually it's not my own style, I'm driven
  10.     to use it by a stupid Lint-like program I use called 'ccheck'.
  11. */
  12.  
  13. #define  PRIORITY              10L
  14. #define  NBR_IOA_STRUCTS      10L
  15. #define  PV_IOA_STRUCT           0L
  16. #define  FIN_IOA_STRUCT           9L
  17. #define  BIG_WAVE             256L
  18. #define  NBR_WAVES               7L
  19. #define  WAVES_TOTAL        1024L
  20. #define  YES                   1L
  21. #define  NO                       0L
  22.  
  23. extern struct MsgPort *CreatePort();
  24. extern void *AllocMem();
  25.  
  26. void clear_audio (int);
  27.  
  28. UBYTE aMap[] = { 0x0f };
  29. long  voiceMap[] = { 1, 2, 4, 8 };
  30. struct IOAudio *ioa, *finishioa, *ioapv;
  31. struct IOAudio *ioainuse[4];
  32. struct IOAudio *freeioa[4];
  33. long unitno = 1;
  34. int error;
  35. int waiting[4] = { NO, NO, NO, NO };
  36. int woffsets[] =
  37.     { 0, 256, 384, 448, 480, 496, 504, 508, 510 };
  38. int wlen[] =
  39.     { 256, 128, 64, 32, 16, 8, 4, 2, 1 };
  40. int perval[] =
  41.     { 428, 404, 381, 360, 339, 320, 302, 285, 269, 254, 240, 226, 214 };
  42. BYTE *wptr;
  43. BYTE *owptr[4] = { NULL, NULL, NULL, NULL };
  44.  
  45. char *portstring[] =
  46.     {
  47.     "Audio one",
  48.     "Audio two",
  49.     "Audio three",
  50.     "Audio four",
  51.     "Audio five",
  52.     "Audio six",
  53.     "Audio seven",
  54.     "Audio eight"
  55.     };
  56.  
  57. int get_audio()
  58.     {
  59.     int i;
  60.  
  61.     ioa = (struct IOAudio *)
  62.       AllocMem((NBR_IOA_STRUCTS * (long)sizeof(*ioa)),MEMF_PUBLIC | MEMF_CLEAR);
  63.     if (ioa == NULL)
  64.         {
  65.         clear_audio(1);
  66.         return(0);
  67.         }
  68.  
  69.     for (i = 0; i < 4; ++i)
  70.         {
  71.         ioainuse[i] = &ioa[i + 1];
  72.         freeioa[i] = &ioa[i + 5];
  73.         }
  74.     ioapv = &ioa[PV_IOA_STRUCT];
  75.     finishioa = &ioa[FIN_IOA_STRUCT];
  76.  
  77.     ioa->ioa_Request.io_Message.mn_Node.ln_Pri = PRIORITY;
  78.     ioa->ioa_Request.io_Message.mn_ReplyPort =
  79.         CreatePort("Audio zero", 0L);
  80.     if (ioa->ioa_Request.io_Message.mn_ReplyPort == NULL)
  81.         {
  82.         clear_audio(2);
  83.         return(0);
  84.         }
  85.     ioa->ioa_Data = aMap;
  86.     ioa->ioa_Length = (long)sizeof(aMap);
  87.     error = OpenDevice(AUDIONAME, 0L, (struct ioRequest *) ioa, 0L);
  88.     if (error)
  89.         {
  90.         clear_audio(3);
  91.         return(0);
  92.         }
  93.  
  94.     *finishioa = *ioa;
  95.     finishioa->ioa_Request.io_Flags = IOF_QUICK;
  96.     ioapv->ioa_Request.io_Flags = IOF_QUICK;
  97.  
  98.     finishioa->ioa_Request.io_Command = ADCMD_FINISH;
  99.     ioapv->ioa_Request.io_Command = ADCMD_PERVOL;
  100.  
  101.     for (i = 0; i < 4; ++i)
  102.         {
  103.         *freeioa[i] = *ioa;
  104.         *ioainuse[i] = *ioa;
  105.         freeioa[i]->ioa_Request.io_Message.mn_ReplyPort =
  106.             CreatePort(portstring[i], 0L);
  107.         ioainuse[i]->ioa_Request.io_Message.mn_ReplyPort =
  108.             CreatePort(portstring[i + 4], 0L);
  109.         }
  110.     for (i = 0; i < 4; ++i)
  111.         if
  112.           (
  113.                 freeioa[i]->ioa_Request.io_Message.mn_ReplyPort == NULL ||
  114.                 ioainuse[i]->ioa_Request.io_Message.mn_ReplyPort == NULL
  115.           )
  116.                 {
  117.                 clear_audio(4);
  118.                 return (0);
  119.                 }
  120.     return (makewaves());
  121.     }
  122.  
  123. void clear_audio(finishcode)
  124.     int finishcode;
  125.     {
  126.     int i;
  127.  
  128.     switch(finishcode)
  129.         {
  130.     case 0:
  131.  
  132.         FreeMem(wptr, WAVES_TOTAL);
  133.  
  134.     case 4:
  135.     case 5:
  136.  
  137.         for (i = 0; i < 4; ++i)
  138.             {
  139.             if (freeioa[i]->ioa_Request.io_Message.mn_ReplyPort)
  140.                 DeletePort(freeioa[i]->ioa_Request.io_Message.mn_ReplyPort);
  141.             if (ioainuse[i]->ioa_Request.io_Message.mn_ReplyPort)
  142.                 DeletePort(ioainuse[i]->ioa_Request.io_Message.mn_ReplyPort);
  143.             }
  144.  
  145.  
  146.         CloseDevice((struct ioRequest *) ioa);
  147.  
  148.     case 3:
  149.  
  150.         DeletePort(ioa->ioa_Request.io_Message.mn_ReplyPort);
  151.  
  152.     case 2:
  153.  
  154.         FreeMem(ioa, (NBR_IOA_STRUCTS * (long)sizeof(*ioa)));
  155.  
  156.         }
  157.  
  158.     }
  159.  
  160. void setwpv(wf, len, per, vol, voice)
  161.     char *wf;
  162.     int len, per, vol, voice;
  163.     {
  164.     struct IOAudio *tmpioa;
  165.  
  166.     freeioa[voice]->ioa_Request.io_Command = CMD_WRITE;
  167.     freeioa[voice]->ioa_Request.io_Flags = ADIOF_PERVOL | IOF_QUICK;
  168.     freeioa[voice]->ioa_Cycles = 0;
  169.  
  170.     freeioa[voice]->ioa_Request.io_Unit = (struct Unit *)unitno;
  171.     finishioa->ioa_Request.io_Unit = (struct Unit *)unitno;
  172.  
  173.  
  174.     freeioa[voice]->ioa_Data = (UBYTE *)wf;
  175.     freeioa[voice]->ioa_Length = len;
  176.     freeioa[voice]->ioa_Period = per;
  177.     freeioa[voice]->ioa_Volume = vol;
  178.  
  179.     if (waiting[voice])
  180.         {
  181.         BeginIO((struct ioRequest *) finishioa);
  182.         WaitIO((struct ioRequest *) ioainuse[voice]);
  183.         waiting[voice] = NO;
  184.         }
  185.  
  186.  
  187.     BeginIO((struct ioRequest *) freeioa[voice]);
  188.     error = CheckIO((struct ioRequest *) freeioa[voice]);
  189.     if (error)
  190.         WaitIO((struct ioRequest *) freeioa[voice]);
  191.         
  192.     waiting[voice] = YES;
  193.  
  194.     tmpioa = ioainuse[voice];
  195.     ioainuse[voice] = freeioa[voice];
  196.     freeioa[voice] = tmpioa;
  197.     }
  198.  
  199. void setpv(per, vol)
  200.     int per, vol;
  201.     {
  202.     ioapv->ioa_Period = per;
  203.     ioapv->ioa_Volume = vol;
  204.     ioapv->ioa_Request.io_Unit = (struct Unit *)unitno;
  205.     BeginIO((struct ioRequest *) ioapv);
  206.     }
  207.  
  208. void StopVoices()
  209.     {
  210.     int voice;
  211.  
  212.     for (voice = 0; voice < 4; ++voice)
  213.         {
  214.         if (waiting[voice])
  215.             {
  216.             unitno = voiceMap[voice];
  217.             setpv(128, 0);
  218.             finishioa->ioa_Request.io_Unit = (struct Unit *)unitno;
  219.             BeginIO((struct ioRequest *) finishioa);
  220.             WaitIO((struct ioRequest *) ioainuse[voice]);
  221.             waiting[voice] = NO;
  222.             }
  223.         }
  224.     }
  225.  
  226. void setwave(wfp)
  227.     UBYTE *wfp;
  228.     {
  229.     int i;
  230.  
  231.     for (i = 0; i < BIG_WAVE; ++i)
  232.         wfp[i] = i;
  233.     }
  234.  
  235. void xpandwave(wfp)
  236.     BYTE *wfp;
  237.     {
  238.     int i, j, rate;
  239.     BYTE *tptr;
  240.  
  241.     rate = 1;
  242.     tptr = wfp + BIG_WAVE;
  243.     for (i = 0; i < NBR_WAVES - 1; ++i)
  244.         {
  245.         rate *= 2;
  246.         for (j = 0; j < BIG_WAVE; j += rate)
  247.             *tptr++ = wfp[j];
  248.         }
  249.     }
  250.  
  251. int makewaves()
  252.     {
  253.     wptr = (BYTE *)AllocMem(WAVES_TOTAL, MEMF_CHIP);
  254.     if (wptr == NULL)
  255.         {
  256.         clear_audio(5);
  257.         return (0);
  258.         }
  259.  
  260.     setwave(wptr);
  261.     xpandwave(wptr);
  262.     return (1);
  263.     }
  264.  
  265. void play_note(note, voice)
  266.     int note, voice;
  267.     {
  268.     int per, oct;
  269.     BYTE *wfp;
  270.  
  271.     unitno = voiceMap[voice];
  272.     if (note >= 100)
  273.         {
  274.         if (waiting[voice])
  275.             setpv(200, 0);
  276.         return;
  277.         }
  278.     oct = note / 12;
  279.     per = perval[note % 12];
  280.     wfp = wptr + woffsets[oct];
  281.  
  282.     if (wfp == owptr[voice])
  283.         setpv(per, 32);
  284.     else
  285.         {
  286.         setwpv(wfp, wlen[oct], per, 32, voice);
  287.         owptr[voice] = wfp;
  288.         }
  289.     }